home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / aztecnos.arc / PC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-21  |  7.9 KB  |  382 lines

  1. /* OS- and machine-dependent stuff for IBM-PC running MS-DOS */
  2. #include <stdio.h>
  3. #include <sgtty.h>
  4. #include "global.h"
  5. #include "mbuf.h"
  6. #include "internet.h"
  7. #include "iface.h"
  8. #include "cmdparse.h"
  9. #include "regs.h"
  10.  
  11. extern FILE *Logfp;
  12. extern void (*Tvec)();    /* Linkage to previous INT 1C vector */
  13. void btick(),nullvec();
  14. void (*getvect())();
  15. unsigned grabcore();
  16. char *getenv();
  17. static int vspsub();
  18.  
  19.  
  20. /* This flag is set by setirq() if IRQ 8-15 is used, indicating
  21.  * that the machine is a PC/AT with a second 8259 interrupt controller.
  22.  * If this flag is set, the interrupt return code in pcgen.asm will
  23.  * send an End of Interrupt command to the second 8259 as well as the
  24.  * first.
  25.  */
  26. char Isat;    
  27.  
  28. /* Interface list header */
  29. struct iface *Ifaces;
  30.  
  31. /* Aztec memory allocation control */
  32. int _STKLOW = 0;    /* Stack above heap */
  33. int _STKSIZ = 16384/16;    /* 16K stack -- overridden in grabcore */
  34. int _HEAPSIZ = 4096/16;    /* Isn't really used */
  35. int _STKRED = 4096;    /* Stack red zone in bytes -- this really matters */
  36.  
  37. char Ttbuf[BUFSIZ];
  38.  
  39. /* Keyboard input buffer */
  40. #define    KBSIZE    256
  41. struct {
  42.     char buf[KBSIZE];
  43.     char *wp;
  44.     char *rp;
  45.     int cnt;
  46. } Keyboard;
  47.  
  48. /* Called at startup time to set up console I/O, memory heap */
  49. ioinit()
  50. {
  51.     struct sgttyb ttybuf;
  52.  
  53.     /* Ignore ctrl-breaks */
  54.     setvect(0x23,nullvec);
  55.  
  56.     /* Save these two file table entries for something more useful */
  57.     fclose(stdaux);
  58.     fclose(stdprt);
  59.  
  60.     /* Interrupts use a special stack deep in data space.
  61.      * Calls to sbrk() (invoked by malloc when it needs more memory
  62.      * from the system) at interrupt time will fail because sbrk()
  63.      * will think that the stack has overwritten the heap. So
  64.      * grab all the memory we can now for the heap so that malloc
  65.      * won't have to call sbrk and alloc_mbuf() won't fail unnecessarily
  66.      * at interrupt time.
  67.      */
  68.     grabcore(0xf000);
  69.  
  70.     setbuf(stdout,Ttbuf);
  71.  
  72.     /* Put display in raw mode. Note that this breaks tab expansion,
  73.      * so you need to run NANSI.SYS or equivalent.
  74.      */
  75.     ioctl(1,TIOCGETP,&ttybuf);
  76.     ttybuf.sg_flags = RAW;
  77.     ioctl(1,TIOCSETP,&ttybuf);
  78.  
  79.     /* Grab BIOS hook for 18 Hz clock tick, reading previous value
  80.      * into tvec so the assembler stub will link to it.
  81.      */
  82.     Tvec = getvect(0x1c);
  83.     setvect(0x1c,btick);
  84.  
  85.     /* Find out what multitasker we're running under, if any */
  86.     chktasker();
  87.  
  88.     /* Initialize keyboard queue */
  89.     Keyboard.rp = Keyboard.wp = Keyboard.buf;
  90.  
  91. }
  92. /* Called just before exiting to restore console state */
  93. iostop()
  94. {
  95.     struct sgttyb ttybuf;
  96.  
  97.     if(Logfp != NULLFILE){
  98.         fclose(Logfp);
  99.         Logfp = NULLFILE;
  100.     }
  101.     setbuf(stdout,NULLCHAR);
  102.     ioctl(1,TIOCGETP,&ttybuf);
  103.     ttybuf.sg_flags &= ~RAW;
  104.     ioctl(1,TIOCSETP,&ttybuf);
  105.     while(Ifaces != NULLIF){
  106.         if(Ifaces->stop != NULLFP)
  107.             (*Ifaces->stop)(Ifaces);
  108.         Ifaces = Ifaces->next;
  109.     }
  110.     setvect(0x1c,Tvec);    /* Restore original timer tick vector */
  111. }
  112. /* Spawn subshell */
  113. doshell(argc,argv)
  114. {
  115.     char *command;
  116.     struct sgttyb ttybuf,ttysav;
  117.     int ret;
  118.  
  119.     ioctl(1,TIOCGETP,&ttysav);
  120.     ioctl(1,TIOCGETP,&ttybuf);
  121.     ttybuf.sg_flags &= ~RAW;
  122.     ioctl(1,TIOCSETP,&ttybuf);
  123.  
  124.     if((command = getenv("COMSPEC")) == NULLCHAR)
  125.         command = "/COMMAND.COM";
  126.     ret = fexecl(command,command,NULLCHAR);
  127.     ioctl(1,TIOCSETP,&ttysav);
  128.     if(ret == -1)
  129.         return -1;
  130.     else
  131.         return wait();
  132. }
  133.  
  134. /* Keyboard interrupt handler */
  135. void
  136. kbint()
  137. {
  138.     int sig = 0;
  139.     int c;
  140.  
  141.     while((c = kbraw()) != -1 && Keyboard.cnt < KBSIZE){
  142.         sig = 1;
  143.         *Keyboard.wp++ = c;
  144.         if(Keyboard.wp == &Keyboard.buf[KBSIZE])
  145.             Keyboard.wp = Keyboard.buf;
  146.         Keyboard.cnt++;
  147.     }
  148.     if(sig){
  149.         psignal(&Keyboard,1);
  150.     }
  151. }
  152. static int
  153. kbchar()
  154. {
  155.     char i_state;
  156.     char c;
  157.  
  158.     i_state = dirps();
  159.     while(Keyboard.cnt == 0)
  160.         pwait(&Keyboard);
  161.     c = *Keyboard.rp++;
  162.     if(Keyboard.rp == &Keyboard.buf[KBSIZE])
  163.         Keyboard.rp = Keyboard.buf;
  164.     Keyboard.cnt--;
  165.     restore(i_state);
  166.     return c;
  167. }
  168. /* Read characters from the keyboard, translating them to "real" ASCII.
  169.  * If none are ready, block. The F-10 key is special; translate it to -2.
  170.  */
  171. int
  172. kbread()
  173. {
  174.     int c;
  175.  
  176.     if((c = kbchar()) == 0){
  177.         /* Lead-in to a special char */
  178.         c = kbchar();
  179.         switch(c){
  180.         case 3:        /* NULL (bizzare!) */
  181.             c = 0;
  182.             break;
  183.         case 68:    /* F-10 key (used as command-mode escape) */
  184.             c = -2;
  185.             break;
  186.         case 83:    /* DEL key */
  187.             c = 0x7f;
  188.             break;
  189.         default:    /* Dunno what it is */
  190.             c = -1;
  191.         }
  192.     }
  193.     return c;
  194. }
  195. #define    CTLZ    26
  196. /* Special version of aputc() (used by putchar and printf) that filters
  197.  * out nasty characters that screw up the DDOS and ANSI terminal drivers
  198.  */
  199. aputc(c,file)
  200. char c;
  201. FILE *file;
  202. {
  203.     /* Nulls get displayed as spaces by ansi.sys (wrong)
  204.      * ^Z's seem to hang the DoubleDos and DesqView screen drivers
  205.      */
  206.     if((c == '\0' || c == CTLZ) && file == stdout)
  207.         return c;
  208.     /* Do end-of-line translations */
  209.     if(c == '\n')
  210.         putc('\r',file);
  211.     return putc(c,file);
  212. }
  213. /* This ANSI standard library function seems to be missing from Aztec */
  214. static char *vs_buff;
  215. int
  216. vsprintf(str,fmt,args)
  217. char *str;
  218. char *fmt;
  219. char *args;
  220. {
  221.     register int i;
  222.  
  223.     vs_buff = str;
  224.     i = format(vspsub,fmt,args);
  225.     *vs_buff = 0;
  226.     return i;
  227. }
  228. static int
  229. vspsub(c)
  230. char c;
  231. {
  232.     return (*vs_buff++ = c)&0xff;
  233. }
  234.  
  235. /* Called from the timer routine on each tick */
  236. systick()
  237. {
  238.     /* Tickle the keyboard interrupt. This nonsense is
  239.      * necessary because there's no way to get a hardware interrupt
  240.      * from the BIOS.
  241.      */
  242.     kbint();
  243.  
  244.     /* Flush out console. This gains efficiency in telnet
  245.      * since it only handles a character at a time, at the cost
  246.      * of a slight echo delay.
  247.      */
  248.     fflush(stdout);
  249. }
  250. /* Reset the CPU, reboot DOS */
  251. sysreset()
  252. {
  253.     int16 regs[8];    /* Not really needed */
  254.  
  255.     farcall(0x0,0xffff,regs,regs);
  256. }
  257.  
  258. /* Install hardware interrupt handler.
  259.  * Takes IRQ numbers from 0-7 (0-15 on AT) and maps to actual 8086/286 vectors
  260.  * Note that bus line IRQ2 maps to IRQ9 on the AT
  261.  */
  262. setirq(irq,handler)
  263. unsigned irq;
  264. void (*handler)();
  265. {
  266.     /* Set interrupt vector */
  267.     if(irq < 8){
  268.         setvect(8+irq,handler);
  269.     } else if(irq < 16){
  270.         Isat = 1;
  271.         setvect(0x70 + irq - 8,handler);
  272.     } else {
  273.         return -1;
  274.     }
  275.     return 0;
  276. }
  277. /* Return pointer to hardware interrupt handler.
  278.  * Takes IRQ numbers from 0-7 (0-15 on AT) and maps to actual 8086/286 vectors
  279.  */
  280. void
  281. (*getirq(irq))()
  282. unsigned int irq;
  283. {
  284.     /* Set interrupt vector */
  285.     if(irq < 8){
  286.         return getvect(8+irq);
  287.     } else if(irq < 16){
  288.         return getvect(0x70 + irq - 8);
  289.     } else {
  290.         return NULLVFP;
  291.     }
  292. }
  293. /* Disable hardware interrupt */
  294. maskoff(irq)
  295. unsigned irq;
  296. {
  297.     if(irq < 8){
  298.         setbit(0x21,(char)(1<<irq));
  299.     } else if(irq < 16){
  300.         irq -= 8;
  301.         setbit(0xa1,(char)(1<<irq));
  302.     } else {
  303.         return -1;
  304.     }
  305.     return 0;
  306. }
  307. /* Enable hardware interrupt */
  308. maskon(irq)
  309. unsigned irq;
  310. {
  311.     if(irq < 8){
  312.         clrbit(0x21,(char)(1<<irq));
  313.     } else if(irq < 16){
  314.         irq -= 8;
  315.         clrbit(0xa1,(char)(1<<irq));
  316.     } else {
  317.         return -1;
  318.     }
  319.     return 0;
  320. }
  321. /* Return 1 if specified interrupt is enabled, 0 if not, -1 if invalid */
  322. getmask(irq)
  323. unsigned irq;
  324. {
  325.     if(irq < 8)
  326.         return (inportb(0x21) & (1 << irq)) ? 0 : 1;
  327.     else if(irq < 16){
  328.         irq -= 8;
  329.         return (inportb(0xa1) & (1 << irq)) ? 0 : 1;
  330.     } else
  331.         return -1;
  332. }
  333. /* Called from assembler stub linked to BIOS interrupt 1C, called on each
  334.  * hardware clock tick. Signal a clock tick to the timer process.
  335.  */
  336. int Tick;
  337. ctick()
  338. {
  339.     Tick++;
  340.     psignal(&Tick,1);
  341. }
  342. /* Set bit(s) in I/O port */
  343.  
  344. setbit(port,bits)
  345. unsigned port;
  346. char bits;
  347. {
  348.     outportb(port,(char)inportb(port)|bits);
  349. }
  350. /* Clear bit(s) in I/O port */
  351. clrbit(port,bits)
  352. unsigned port;
  353. char bits;
  354. {
  355.     outportb(port,(char)(inportb(port) & ~bits));
  356. }
  357. /* Convert a pointer to a long integer */
  358. long
  359. ptol(p)
  360. void *p;
  361. {
  362.     long x;
  363.  
  364.     x = FP_OFF(p);
  365. #ifdef    LARGEDATA
  366.     x |= (long)FP_SEG(p) << 16;
  367. #endif
  368.     return x;
  369. }
  370. void *
  371. ltop(l)
  372. long l;
  373. {
  374.     register unsigned seg,offset;
  375.  
  376.     seg = l >> 16;
  377.     offset = l;
  378.     return MK_FP(seg,offset);
  379. }
  380.  
  381.  
  382.